#include "Player.h"
#include "../SGD Wrappers/SGD_AudioManager.h"
#include "..\SGD Wrappers\SGD_GraphicsManager.h"
#include "..\SGD Wrappers\SGD_InputManager.h"
#include "..\SGD Wrappers\SGD_Geometry.h"
#include "GameplayState.h"
#include "BaseBehavior.h"
#include "BehaviorManager.h"
#include "EnemyUnit.h"
#include "../SGD Wrappers/SGD_Event.h"
#include "Timer.h"
#include "Game.h"
#include <fstream>
#include "../SGD Wrappers/SGD_Handle.h"


Player::Player() : Listener(this)
{




	m_Attributes.m_fCurrEnergy = 100.0f;
	m_Attributes.m_fMaxEnergy = 100.0f;
	//szSize = {68, 64};
	RegisterForEvent("PICK_UP_KEY");
	RegisterForEvent("PICK_UP_CORE");

	RegisterForEvent("CHECKPOINT");
	RegisterForEvent("INTERACT_WITH");
	RegisterForEvent("SHADOW_HIDE");

	RegisterForEvent("LEVEL_COMPLETE");
	RegisterForEvent("DONE_HIT");
	RegisterForEvent("TAKEDOWN");

	RegisterForEvent("PLAY_SOUND_FOOTSTEP");
	RegisterForEvent("HIT");



	m_hDeath = &GameplayState::GetInstance()->playerDeath;

	voice = SGD::INVALID_HANDLE;



	hud.Initialize();

	float		rectoffset	= 9.0f;
	float		rectheight	= 112.0f;

	m_rectAbilityPoint	= { 13.0f, Game::GetInstance()->GetScreenHeight() - 112.0f + 6.0f };
	m_rectAbilitySize	= { 95.0f, 102.0f };

}


Player::~Player()
{
	m_hDeath = nullptr;
	UnregisterFromEvent("PICK_UP_KEY");
	UnregisterFromEvent("PICK_UP_CORE");
	
	UnregisterFromEvent("CHECKPOINT");
	UnregisterFromEvent("INTERACT_WITH");
	UnregisterFromEvent("LEVEL_COMPLETE");
	UnregisterFromEvent("DONE_HIT");
	UnregisterFromEvent("TAKEDOWN");
	UnregisterFromEvent("PLAY_SOUND_FOOTSTEP");
	UnregisterFromEvent("HIT");

	hud.Shutdown();

}

/*virtual*/ void Player::Update(float dt)	 /*override*/
{
	if (controller != nullptr)
		controller->Update(dt, this, { 0, 0 });

	if (m_bIsCamoOn)
	{
		m_unVisibleState = CAMO;
		m_Attributes.m_fCurrEnergy -= (m_Attributes.m_fCamoCost * m_Attributes.m_fCamoMultiplier) * dt;

 		if (m_Attributes.m_fCurrEnergy < 0.0f)
		{
			m_Attributes.m_fCurrEnergy = 0.0f;
			m_bIsCamoOn = false;
			m_unVisibleState = VISIBLE;
		}
	}
	else  
	{
		if (m_unVisibleState != SHADOWED)
			m_unVisibleState = VISIBLE;
	}
	
	if (m_bIsSprinting == true)
	{
		m_Attributes.m_fCurrStamina -= (m_Attributes.m_fSprintCost * dt);

		if (m_Attributes.m_fCurrStamina < 0.0f)
		{
			m_Attributes.m_fCurrStamina = 0.0f;
			m_bIsSprinting = false;
		}
	}

	if (m_Attributes.m_fCurrEnergy < m_Attributes.m_fMaxEnergy && m_bIsCamoOn == false)
	{
		if (energyReboot.Update(dt))
			m_Attributes.m_fCurrEnergy += m_Attributes.m_fEnergyRegen * dt;
		if (m_Attributes.m_fCurrEnergy > m_Attributes.m_fMaxEnergy)
			m_Attributes.m_fCurrEnergy = m_Attributes.m_fMaxEnergy;

	}
	if (m_Attributes.m_fCurrStamina < m_Attributes.m_fMaxStamina)
	{
		if (m_bIsSprinting == false && m_bCarryingEnemy == false)
		{
			if (m_bMoving == false)
				m_Attributes.m_fCurrStamina += m_Attributes.m_fStaminaRegen * dt;
			else
				m_Attributes.m_fCurrStamina += (m_Attributes.m_fStaminaRegen *0.5f) * dt;

		}
	
	}


	switch (m_unCurrAbility)
	{
	case 0: // Camo
		m_rectAbilityPoint.x	= 13.0f;
		m_rectAbilitySize		= { 95.0f, 102.0f };
		break;

	case 1: //Radar
		m_rectAbilityPoint.x	= 116.0f;
		m_rectAbilitySize		= { 104.0f, 102.0f };
		break;

	case 2: // Takedown
		m_rectAbilityPoint.x	= 226.0f;
		m_rectAbilitySize		= { 104.0f, 102.0f };
		break;

	case 3: // EMP/Stun
		m_rectAbilityPoint.x	= 336.0f;
		m_rectAbilitySize		= { 104.0f, 102.0f };
		break;

	default:
		break;
	}
	



	hud.Update(dt);

	MovingObject::Update(dt);
}

void Player::Render()
{
	
	BaseObject::Render();
	hud.Render();


	SGD::GraphicsManager::GetInstance()->DrawRectangle(SGD::Rectangle(m_rectAbilityPoint, m_rectAbilitySize), { 0, 0, 0, 0 }, { 255, 0, 255, 0 });
}

/*virtual*/ void Player::HandleEvent(const SGD::Event* pEvent)
{
	if (pEvent->GetEventID() == "PICK_UP_KEY")
	{
		m_bHasKey = true;
	}
	else if (pEvent->GetEventID() == "PICK_UP_CORE")
	{
		m_Attributes.m_fMaxEnergy += m_Attributes.m_fMaxEnergy * 0.10f;
	}
	else if (pEvent->GetEventID() == "PICK_UP_STIM")
	{
		m_Attributes.m_fMaxStamina += m_Attributes.m_fMaxStamina * 0.10f;
	}
	else if (pEvent->GetEventID() == "PICK_UP_DOC")
	{
		m_Attributes.m_fMaxEnergy += m_Attributes.m_fMaxEnergy * 0.10f;
	}
	else if (pEvent->GetEventID() == "HIT")
	{
		m_bIsAlive = false;
	}
	else if (pEvent->GetEventID() == "SHADOW_HIDE")
	{
		if (m_unVisibleState != SPOTTED && m_unVisibleState != SHADOWED && m_vtVelocity == SGD::Vector())
			m_unVisibleState = SHADOWED;

	}
	else if (pEvent->GetEventID() == "INTERACT_WITH")
	{
		m_pInteracting = (BaseObject*)pEvent->GetSender();
	}
	else if (pEvent->GetEventID() == "SPOTTED")
	{
		m_unVisibleState = SPOTTED;
	}
	else if (pEvent->GetEventID() == "LOST")
	{
		m_unVisibleState = VISIBLE;

	}
	else if (pEvent->GetEventID() == "CHECKPOINT")
	{
		profile.CamoMultiplier = m_Attributes.m_fCamoMultiplier;					
		profile.CheckPointReached = true;
		profile.MaxEnergy = m_Attributes.m_fMaxEnergy;
		profile.MaxStamina = m_Attributes.m_fCurrStamina;
		profile.RadarMultiplier = m_Attributes.m_fRadarMultiplier;
		profile.SpeedMultiplier = m_Attributes.m_fSpeedMultiplier;

		fstream file;

		file.open(profile.path.c_str());
		
		if (file.is_open())
		{

			file << profile.path << '\n';
			file << profile.MaxEnergy << '\n';
			file << profile.MaxStamina << '\n';
			file << profile.CamoMultiplier << '\n';
			file << profile.SpeedMultiplier << '\n';
			file << profile.RadarMultiplier << '\n';
			file << profile.LevelsComplete << '\n';
			file << profile.m_bHasKey << '\n';
			file << profile.CheckPointReached << '\n';
			file.close();

		}

	}
	else if (pEvent->GetEventID() == "PLAY_SOUND_FOOTSTEP")
	{
		SGD::AudioManager* pAudio = SGD::AudioManager::GetInstance();
		SGD::HAudio step = GameplayState::GetInstance()->footstep;

		if (pAudio->IsAudioPlaying(step) == false)
			voice = pAudio->PlayAudio(step, false);

		pAudio->SetVoiceVolume(voice);

	}
	else if (pEvent->GetEventID() == "LEVEL_COMPLETE")
	{
		profile.CamoMultiplier = m_Attributes.m_fCamoMultiplier;
		profile.CheckPointReached = true;
		profile.MaxEnergy = m_Attributes.m_fMaxEnergy;
		profile.MaxStamina = m_Attributes.m_fCurrStamina;
		profile.RadarMultiplier = m_Attributes.m_fRadarMultiplier;
		profile.SpeedMultiplier = m_Attributes.m_fSpeedMultiplier;

		Game::GetInstance()->GetProfile() = profile;
		fstream file;

		file.open(profile.path.c_str());

		if (file.is_open())
		{

			file << profile.path << '\n';
			file << profile.MaxEnergy << '\n';
			file << profile.MaxStamina << '\n';
			file << profile.CamoMultiplier << '\n';
			file << profile.SpeedMultiplier << '\n';
			file << profile.RadarMultiplier << '\n';
			file << (profile.LevelsComplete+1) << '\n';
			file << profile.m_bHasKey << '\n';
			file << profile.CheckPointReached << '\n';
			file.close();

		}
		m_bLevelCompleted = true;

	}
	else if (pEvent->GetEventID() == "TAKEDOWN")
	{
		m_nAttackState = ATTACKING;
	}
	else if (pEvent->GetEventID() == "DONE_HIT")
	{
		m_nAttackState = NOT_ATTACKING;
		animation.m_strCurrAnimation = "playerIdle";
		animation.m_fCurrDuration = 0.0f;
		animation.m_nCurrFrame = 0;

	}
}
/*virtual*/ void Player::HandleCollision(const IBase* pOther) /*override*/
{
	switch (pOther->GetType())
	{
	case OBJ_BULLET:
	case OBJ_DOG:
		m_bIsAlive = false;
		return;
	case OBJ_GUARD:
	case OBJ_ELITE_GUARD:
	case OBJ_OFFICER:
	case OBJ_WORKER:
	case OBJ_WALL:
	case OBJ_DOOR:
		break;
	//	MovingObject::HandleCollision(pOther);

	}

}


///*virtual*/ SGD::Rectangle	Player::GetRect(void)	const
//{
//	return SGD::Rectangle();
//}

void Player::RetrieveBehavior(std::string name)
{

	if (controller != nullptr)
	{
		controller = nullptr;
	}
	controller = BehaviorManager::GetInstance()->GetBehaviors()[name];
}
/*virtual*/ void Player::Attack(void)
{


}


